package com.ctshk.rpc.user.service.impl;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.Currency;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.enums.appUser.TransactionIntegralOperateType;
import com.ctshk.common.enums.appUser.TransactionIntegralStatus;
import com.ctshk.common.enums.appUser.TransactionType;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.starvip.dto.start_vip.transaction.LoyTransaction;
import com.ctshk.rpc.starvip.req.TransactionIntegralCommonReq;
import com.ctshk.rpc.starvip.service.IStarVipBusinessService;
import com.ctshk.rpc.user.dto.TransactionIntegralLogDTO;
import com.ctshk.rpc.user.req.TransactionIntegralLogReq;
import com.ctshk.rpc.user.req.UserTransactionIntegralCommonReq;
import com.ctshk.rpc.user.service.ITransactionIntegralLogService;
import com.ctshk.rpc.user.service.ITransactionIntegralService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;

/**
 * <p>
 * 会员积分交易服务
 * </p>
 *
 * @author 李新科
 * @date 2021/6/30 15:56
 */
@DubboService(validation = "true")
@Slf4j
public class TransactionIntegralServiceImpl implements ITransactionIntegralService {

    @DubboReference
    private IStarVipBusinessService starVipBusinessService;

    @DubboReference
    private ITransactionIntegralLogService transactionIntegralLogService;

    @Override
    public Result transactionIntegralCommon(UserTransactionIntegralCommonReq req) {
        boolean exists = transactionIntegralLogService.exists(req.getOrderId(), TransactionType.getStarVipCodeByCode(req.getTransactionType()));
        if(!exists) {
            // 保存交易记录
            Long id = transactionIntegralLogService.save(new TransactionIntegralLogReq()
                    .setOrderId(req.getOrderId())
                    .setMemberId(req.getMemberId())
                    .setCtsOrderNum(req.getOrderNumber())
                    .setBusinessType(req.getSystemBusinessType())
                    .setPoints(req.getUsePoints())
                    .setAmount(req.getReceivableAmount())
                    .setCurrencyCode(req.getCurrency())
                    .setTransactionType(TransactionType.getStarVipCodeByCode(req.getTransactionType()))
                    .setOrderSource(req.getOrderSource())
                    .setCustomerId(req.getUserId())
                    .setOperateType(TransactionIntegralOperateType.NORMAL.getCode())
            );

            // 星赏会交易
            Result<LoyTransaction> loyTransactionResult = starVipBusinessService.transactionIntegralCommon(new TransactionIntegralCommonReq()
                    .setMemberId(req.getMemberId())
                    .setOrderNumber(req.getOrderNumber())
                    .setSystemBusinessType(req.getSystemBusinessType())
                    .setReceivableAmount(req.getReceivableAmount())
                    .setCurrency(req.getCurrency())
                    .setTransactionType(req.getTransactionType())
                    .setOrderSource(req.getOrderSource())
                    .setUsePoints(req.getUsePoints())
            );

            if(loyTransactionResult.isSuccess()) {
                // 成功则更新交易记录的状态
                LoyTransaction data = loyTransactionResult.getData();
                String status = data.getStatus();
                if(TransactionIntegralStatus.PROCESSED.getStarVipCode().equals(status)) {
                    TransactionIntegralLogReq copy = EntityUtil.copy(data, TransactionIntegralLogReq.class);
                    copy.setId(id);
                    copy.setPoints(copy.getPoints());
                    copy.setOrderId(req.getOrderId());
                    copy.setBusinessType(req.getSystemBusinessType());
                    copy.setOrderSource(req.getOrderSource());
                    copy.setOperateType(TransactionIntegralOperateType.NORMAL.getCode());
                    copy.setStatus(TransactionIntegralStatus.PROCESSED.getCode());
                    copy.setCtsRMBAmount(data.getCtsRMBAmount());
                    copy.setTransactionChannel(String.valueOf(data.getTransactionChannel()));
                    copy.setCurrencyCode(null);
                    copy.setAvailablePoints(data.getPoint1Value());
                    transactionIntegralLogService.update(copy);
                }
            } else {
                return loyTransactionResult;
            }
        } else {
            return Result.failed(SystemError.SYS_445);
        }
        return Result.success();
    }

    @Override
    public Result cancelTransactionIntegralCommon(Long orderId) {
        List<TransactionIntegralLogDTO> transactionIntegralLogDTOS = transactionIntegralLogService.selectListByOrderId(orderId);
        List<TransactionIntegralLogDTO> cancelList = new ArrayList<>();
        for (TransactionIntegralLogDTO transactionIntegralLogDTO : transactionIntegralLogDTOS) {
            if(TransactionIntegralStatus.PROCESSED.getCode().equals(transactionIntegralLogDTO.getStatus())) {
                if(TransactionIntegralOperateType.NORMAL.getCode().equals(transactionIntegralLogDTO.getOperateType())) {
                    cancelList.add(transactionIntegralLogDTO);
                }
            } else {
                // 存在交易未完成的情况报错提示
                return Result.failed(SystemError.SYS_444);
            }
        }
        if(CollectionUtils.isNotEmpty(cancelList)) {
            for (TransactionIntegralLogDTO transactionIntegralLogDTO : cancelList) {
                TransactionIntegralLogReq save = EntityUtil.copy(transactionIntegralLogDTO, TransactionIntegralLogReq.class);
                save.setOperateType(TransactionIntegralOperateType.CANCEL.getCode());
                // 保存交易记录
                Long id = transactionIntegralLogService.save(save);
                // 星赏会交易
                Result<LoyTransaction> loyTransactionResult = starVipBusinessService.cancelTransactionIntegralCommon(new TransactionIntegralCommonReq()
                        .setMemberId(transactionIntegralLogDTO.getMemberId())
                        .setOrderNumber(transactionIntegralLogDTO.getCtsOrderNum())
                        .setSystemBusinessType(transactionIntegralLogDTO.getBusinessType())
                        .setReceivableAmount(transactionIntegralLogDTO.getAmount())
                        .setCurrency(transactionIntegralLogDTO.getCurrencyCode())
                        .setTransactionType(TransactionType.getCodeByStarVipCode(transactionIntegralLogDTO.getTransactionType()))
                        .setOrderSource(transactionIntegralLogDTO.getOrderSource())
                        .setUsePoints(transactionIntegralLogDTO.getPoints())
                        .setQualifyingFlag(transactionIntegralLogDTO.getQualifyingFlag())
                        .setCtsQualifyTxnFlag(transactionIntegralLogDTO.getCtsQualifyTxnFlag())
                );
                if(loyTransactionResult.isSuccess()) {
                    // 成功则更新交易记录的状态
                    LoyTransaction data = loyTransactionResult.getData();
                    String status = data.getStatus();
                    if(TransactionIntegralStatus.PROCESSED.getStarVipCode().equals(status)) {
                        TransactionIntegralLogReq copy = EntityUtil.copy(data, TransactionIntegralLogReq.class);
                        copy.setId(id);
                        copy.setOrderId(save.getOrderId());
                        copy.setBusinessType(save.getBusinessType());
                        copy.setOrderSource(save.getOrderSource());
                        copy.setOperateType(save.getOperateType());
                        copy.setAvailablePoints(data.getPoint1Value());
                        copy.setStatus(TransactionIntegralStatus.PROCESSED.getCode());
                        copy.setCtsRMBAmount(data.getCtsRMBAmount());
                        copy.setTransactionChannel(String.valueOf(data.getTransactionChannel()));
                        transactionIntegralLogService.update(copy);
                    }
                }
            }
        }
        return Result.success();
    }
}
